#include <stdio.h>
#include <unistd.h>
#include <signal.h>

void handler(int signo)
{
    printf("pid: %d, %d 号信号，正在被捕捉！\n", getpid(), signo);
    //  发送消息表明子进程结束，随之而来的可以想到之前的waitpid回收子进程
    //  1.但是问题就是如果有多个子进程同时发送信号，而父进程只会处理一个，从而导致其他的子进程没有回收
    //  waitpid(-1) -> while(1)
    //  2.有很多子进程，但是只有一部分发送信号退出
    // while(1)
    // {
    //     pid_t ret = waitpid(-1, NULL, WNOHANG);
    //     if(ret == 0) break;
    // }

    // printf("%d", quit);
    // quit = 1;
    // printf("-> %d\n", quit);
}

void Count(int cnt)
{
    while(cnt)
    {
        printf("cnt: %2d\r", cnt);
        fflush(stdout);
        cnt--;
        sleep(1);
    }
    printf("\n");
}

int main()
{
    //signal(SIGCHLD, handler);
    //  显示设置对sigchld进行忽略
    signal(SIGCHLD, SIG_IGN);       //  默认是ign 但是手动设置和默认是不一样的
    printf("我是父进程，%d，ppid：%d\n", getpid(), getppid());

    pid_t id = fork();
    if(id == 0)
    {
        printf("我是子进程，%d，ppid：%d，我要退出了\n", getpid(), getppid());
        Count(5);
        exit(1);
    }
    
    while (1) sleep(1);
    
}

// volatile：保持内存可见性
// volatile int quit = 0;

// void handler(int signo)
// {
//     printf("%d 号信号，正在被捕捉！\n", signo);
//     printf("%d", quit);
//     quit = 1;
//     printf("-> %d\n", quit);
// }

// int main()
// {
//     signal(2, handler);
//     // 优化后，内存中quit值被改为1，但是cpu读寄存器内的数据没有改变，因此不会退出循环
//     while (!quit);
//     printf("注意，我是正常退出的！\n");

//     return 0;
// }









// #include <iostream>
// #include <cstdio>
// #include <signal.h>
// #include <unistd.h>

// using namespace std;

// void Count(int cnt)
// {
//     while(cnt)
//     {
//         printf("cnt: %2d\r", cnt);
//         fflush(stdout);
//         cnt--;
//         sleep(1);
//     }
//     printf("\n");
// }

// void handler(int signo)
// {
//     cout << "get a signo" << signo << "正在处理中" << endl;
//     Count(20);
// }

// int main()
// {
//     struct sigaction act, oact;
//     act.sa_handler = handler;
//     act.sa_flags = 0;
//     sigemptyset(&act.sa_mask);      // 当我们正在处理某一种信号的时候，我们也想顺便屏蔽其他信号，就可以添加到这个sa_mask中
//     sigaddset(&act.sa_mask, 3);
//     sigaction(SIGINT, &act, &oact);

//     while (true)
//         sleep(1);

//     return 0;
// }